package com.suxin.queue;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

/**
 * @author Tang
 * @classname BlockQueue
 * @description [  ]
 * @date 2021/6/30 10:44
 */
public class BlockQueue {

    private List<Object> queue = new LinkedList<>();
    private final Integer limit;

    public BlockQueue(Integer limit) {
        this.limit = limit;
    }

    public synchronized void enqueue(Object e) throws Exception {
        while (queue.size() == limit) {
            System.out.println(Thread.currentThread().getName() + "--->队列已满等待取出...");
            wait();
        }
        queue.add(e);
        if (queue.size() >= 1) {
            System.out.println(Thread.currentThread().getName() + "--->插入:" + e);
            notifyAll();
        }
    }

    public synchronized Object deEnqueue() throws Exception {
        while (queue.size() == 0) {
            wait();
        }
        if (queue.size() == limit) {
            notifyAll();
        }
        Object object = queue.remove(0);
        System.out.println(Thread.currentThread().getName() + "--->取出:" + object);
        return object;
    }

    public static void main(String[] args) throws Exception {
        BlockQueue blockQueue = new BlockQueue(5);
        System.out.println("开始并发测试!...");
        IntStream.range(1, 10).parallel()
                .forEach(item -> {
                    new Thread(() -> {
                        try {
                            System.out.println(Thread.currentThread().getName() + "--->" + blockQueue.deEnqueue());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }).start();
                    new Thread(() -> {
                        try {
                            blockQueue.enqueue("hello! " + item);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }).start();
                });
        TimeUnit.SECONDS.sleep(20);
        System.out.println("运行结束....");
    }

}